package com.lagou.handler;

import com.lagou.service.UserServiceImpl;
import com.lagou.util.RpcRequest;
import com.lagou.util.RpcResponse;
import com.lagou.util.SpringContextUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.data.Stat;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class UserServerHandler extends ChannelInboundHandlerAdapter {
    boolean flag =true;
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //判断是否符合约定，符合则调用本地方法，返回数据
        //msg:UserService#sayHello#are you ok?
//        if(msg.toString().startsWith("UserService")){
//            UserServiceImpl userService = new UserServiceImpl();
//            String result =userService.sayHello(msg.toString().substring(msg.toString().lastIndexOf("#")+1));
//            ctx.writeAndFlush(result);
//        }

        //从RpcRequest对象中获取属性 （调用类名，方法，参数等）
        RpcRequest rpcRequest =(RpcRequest)msg;
        String className = rpcRequest.getClassName();
        String methodName = rpcRequest.getMethodName();
        Object[] parameters = rpcRequest.getParameters();
        Class<?>[] parameterTypes = rpcRequest.getParameterTypes();

        Class<?> aClass = Class.forName(className);
        //从spring容器获取对象
        UserServiceImpl o = (UserServiceImpl)SpringContextUtil.getBean(aClass);
        Method method = aClass.getMethod(methodName, parameterTypes);
        //反射调用
        Object result = method.invoke(o, parameters);

        //JDK动态代理
        //UserService proxy = (UserService)createProxy(o);
        //UserServiceImpl proxy = (UserServiceImpl)createProxy(o);
        //Object result = method.invoke(proxy, parameters);

        //返回客户端响应信息
        RpcResponse rpcResponse = new RpcResponse();
        rpcResponse.setMsg((String) result);
        ctx.writeAndFlush(rpcResponse);

        //记录返回时间记录到zookeeper
        ZkClient zkClient = new ZkClient("114.215.81.54:2181");
        Stat stat1=new Stat();
        zkClient.readData("/serverlist/127.0.0.1:8991",stat1);
        //将上次请求时间记录到节点数据内容
        Stat stat2 = zkClient.writeData("/serverlist/127.0.0.1:8991", stat1.getMtime());
        System.out.println("请求时间："+stat1.getMtime());
        System.out.println("返回时间："+stat2.getMtime());
        flag =true;
        //注册节点内容监听
        zkClient.subscribeDataChanges("/serverlist/127.0.0.1:8991", new IZkDataListener() {
            public void handleDataChange(String path, Object data) throws Exception {
                System.out.println(path+"该节点内容被更新，更新后的内容"+data);
                flag=false;
            }

            public void handleDataDeleted(String s) throws Exception {
                System.out.println(s+"该节点被删除");
            }
        });
        Thread.sleep(5000);
        if(flag){
            stat2.setMtime(0);
        }
    }

    public Object createProxy(final Object obj){
        //借助JDK动态代理生成代理对象
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return method.invoke(obj,args);
            }
        });
    }

}
